#include <windows.h>
#include <ocidl.h>
#include <stdio.h>
#include "RealIFeedback.h"
#include "RealICompare.h"

void main()
{
    HRESULT hr;

    hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        fprintf(stderr, "CoInitialize failed with error code: %x\n", hr);
        return;
    }

    IExampleEvts *example;
    hr = CoCreateInstance(CLSID_IExampleEvts, NULL, CLSCTX_INPROC_SERVER, IID_IExampleEvts, (LPVOID *)&example);
    if (FAILED(hr))
    {
        fprintf(stderr, "CoCreateInstance failed with error code: %x\n", hr);
        CoUninitialize();
        return;
    }

    IConnectionPointContainer *container;
    hr = example->QueryInterface(IID_IConnectionPointContainer, (void **)&container);
    if (FAILED(hr))
    {
        fprintf(stderr, "QueryInterface failed with error code: %x\n", hr);
        example->Release();
        CoUninitialize();
        return;
    }

    IConnectionPoint *point;
    hr = container->FindConnectionPoint(DIID_IFeedback, &point);
    if (FAILED(hr))
    {
        fprintf(stderr, "FindConnectionPoint failed with error code: %x\n", hr);
        container->Release();
        example->Release();
        CoUninitialize();
        return;
    }

    DWORD cookie;
    hr = point->Advise(&FeedbackObj, &cookie);
    if (FAILED(hr))
    {
        fprintf(stderr, "Advise failed with error code: %x\n", hr);
        point->Release();
        container->Release();
        example->Release();
        CoUninitialize();
        return;
    }

    hr = example->DoSomething();
    point->Unadvise(cookie);
    point->Release();
    if (FeedbackTypeInfo) FeedbackTypeInfo->Release();
    if (FAILED(hr))
    {
        fprintf(stderr, "DoSomething failed with error code: %x\n", hr);
        container->Release();
        example->Release();
        CoUninitialize();
        return;
    }

    ////////////////////////////////////////////////////////////////////////////////

    IConnectionPoint *point2;
    hr = container->FindConnectionPoint(DIID_ICompare, &point2);
    container->Release();
    if (FAILED(hr))
    {
        fprintf(stderr, "FindConnectionPoint failed with error code: %x\n", hr);
        example->Release();
        CoUninitialize();
        return;
    }

    hr = point2->Advise(&CompareObj, &cookie);
    if (FAILED(hr))
    {
        fprintf(stderr, "Advise failed with error code: %x\n", hr);
        point2->Release();
        example->Release();
        CoUninitialize();
        return;
    }

    DWORD dwArray[] = {5, 3, 1, 4, 2};
    hr = example->Sort(dwArray, _countof(dwArray), sizeof(DWORD));

    point2->Unadvise(cookie);
    point2->Release();
    if (CompareTypeInfo) CompareTypeInfo->Release();
    example->Release();
    CoUninitialize();

    if (FAILED(hr))
    {
        fprintf(stderr, "Sort failed with error code: %x\n", hr);
        return;
    }

    printf("Sorted array:");
    for (int i = 0; i < _countof(dwArray); ++i)
        printf(" %d", dwArray[i]);
    printf("\n");
}
